using MicroMsg.Common.Audio.Amr.Resampler;
using System;
namespace MicroMsg.Common.Audio.Amr
{
	public class AMREncodeFloat
	{
		private MicroMsg.Common.Audio.Amr.Resampler.GloabFunc.ResamplerState pProcess;
		private short[] resamperBuffer;
		private short[] resamperBufferOut;
		private uint outPcm8klen;
		private object m_encoder;
		private short[] pcm8kData;
		private void init_resampler()
		{
			int num = 0;
			this.outPcm8klen = 320u * 8000u / 16000u;
			this.resamperBuffer = new short[320];
			this.resamperBufferOut = new short[2560];
			this.pProcess = MicroMsg.Common.Audio.Amr.Resampler.GloabFunc.resampler_init(1u, 16000u, 8000u, 4, ref num);
		}
		private void uninit_resampler()
		{
			this.resamperBuffer = null;
			this.resamperBufferOut = null;
			if (this.pProcess != null)
			{
				MicroMsg.Common.Audio.Amr.Resampler.GloabFunc.resampler_destroy(this.pProcess);
				this.pProcess = null;
			}
		}
		public AMREncodeFloat()
		{
			this.m_encoder = GloabFunc.Encoder_Interface_init(0);
			this.init_resampler();
		}
		~AMREncodeFloat()
		{
			GloabFunc.Encoder_Interface_exit(this.m_encoder);
			this.uninit_resampler();
		}
		private static void ConvertB2S(byte[] byteArray, int start, int byteLen, short[] shortArray)
		{
			for (int i = 0; i < byteLen; i += 2)
			{
				byte b = byteArray[start + i];
				byte b2 = byteArray[start + i + 1];
				if (BitConverter.IsLittleEndian)
				{
					shortArray[i / 2] = (short)((int)b2 << 8 | (int)b);
				}
				else
				{
					shortArray[i / 2] = (short)((int)b << 8 | (int)b2);
				}
			}
		}
		private bool pcm2amr(short[] short_0, int pcm_len, byte[] byte_0, ref int amr_len, int max_arm_len, bool pitch_shift = false, int pitch_shift_value = 0)
		{
			short[] array = new short[160];
			byte[] array2 = new byte[32];
			Mode mode = Mode.MR515;
			amr_len = 0;
			int i = 0;
			int num = 0;
			while (i < pcm_len)
			{
				int num2 = pcm_len - i;
				if (num2 >= 160)
				{
					GloabFunc.short_copy(short_0, 0, i, 160, array, 0);
					i += 160;
				}
				else
				{
					GloabFunc.short_copy(short_0, 0, i, num2, array, 0);
					i += num2;
				}
				int num3 = GloabFunc.Encoder_Interface_Encode(this.m_encoder, mode, array, array2, 0);
				if (num + num3 < max_arm_len)
				{
					GloabFunc.memcpy(byte_0, num, array2, 0, num3);
					num += num3;
					amr_len += num3;
				}
			}
			return true;
		}
		public bool pcm16K2Amr(byte[] pcm16k, int startOffset, byte[] byte_0, ref int amrlen)
		{
			uint num = 320u;
			AMREncodeFloat.ConvertB2S(pcm16k, startOffset, 640, this.resamperBuffer);
			MicroMsg.Common.Audio.Amr.Resampler.GloabFunc.resampler_process_int(this.pProcess, 0u, this.resamperBuffer, 0, ref num, this.resamperBufferOut, 0, ref this.outPcm8klen);
			if (this.outPcm8klen <= 0u)
			{
				return false;
			}
			this.pcm2amr(this.resamperBufferOut, (int)this.outPcm8klen, byte_0, ref amrlen, 2600, false, 0);
			return amrlen > 0;
		}
		public short[] resample_16kTo8k(byte[] pcm16kData, int offset, int bytesDataLen)
		{
			if (pcm16kData != null && bytesDataLen > 0)
			{
				if (this.pcm8kData == null || this.pcm8kData.Length != bytesDataLen / 4)
				{
					this.pcm8kData = new short[bytesDataLen / 4];
				}
				int i = 0;
				int num = 0;
				while (i < bytesDataLen)
				{
					Buffer.SetByte(this.pcm8kData, num++, Buffer.GetByte(pcm16kData, offset + i));
					Buffer.SetByte(this.pcm8kData, num++, Buffer.GetByte(pcm16kData, offset + i + 1));
					i += 4;
				}
				return this.pcm8kData;
			}
			return null;
		}
		public bool pcm16K2AmrFast(byte[] pcm16k, int startOffset, byte[] byte_0, ref int amrlen)
		{
			short[] array = this.resample_16kTo8k(pcm16k, startOffset, 640);
			this.pcm2amr(array, array.Length, byte_0, ref amrlen, 2600, false, 0);
			return amrlen > 0;
		}
	}
}
